<!DOCTYPE html>
<html lang="en">
<head>
  <meta charset="UTF-8">
  <meta http-equiv="X-UA-Compatible" content="IE=edge">
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
  <title>Document</title>
</head>
<body>
  <script>
    /* 
    1. 引用计数
        根据对象被引用的数量来判断是否是垃圾对象, 数量为0就是垃圾对象
        也就是一旦这个对象没有任何引用指向它, 就是垃圾对象
        问题: 它存在循环引用问题
            对象之间相互有引用指向对方, 即使外部引用都断开了, 它们依然不是垃圾对象(但已经没用了)
    2. 标记清除
        标记所有能找到(递归深度查找)对象, 后面再清除所有没被标记的对象
        从根对象(window)递归查找内部引用的所有对象, 将它们标记为"活的", 后面再清除所有没有被标记的对象(垃圾)
        优点: 没有循环引用问题
        问题:  内存碎片化，导致分配速度慢，浪费内存
        解决: 整理内存空间: 将使用中的内存移动到一边, 将回收空闲的空间移到另一边, 让其成为一段连续的空间
    */

    let o1 = {}  // count = 1
    let o2 = o1   // count  = 2
    o1 = null // count = 1
    o2 = null // count = 0   此时对象就是垃圾对象

    const o3 = {}  // count3 = 1
    const o4 = {} // count4 = 1
    o3.m = o4  // count4 = 2
    o4.n = o3 // count3 = 2
    o3 = null // count3 = 1
    o4 = null // count4 = 1
    // 此时, 根据引用计数的规则这两个对象还不是垃圾对象, 但我们访问不到它们了  => 出现内存泄露的问题


  </script>
</body>
</html>